﻿namespace ICSharpCode.WinFormsUI.Controls
{
    using System;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;

    using ScrollBarResources = ICSharpCode.WinFormsUI.Controls.Properties.Resources;

    /// <summary>
    /// The scrollbar renderer class.
    /// </summary>
    public class NScrollBarRenderer
    {
        protected bool drawThumbGrip = true;

        #region fields

        /// <summary>
        /// The colors of the thumb in the 3 states.
        /// </summary>
        protected Color[,] thumbColors = new Color[3, 8];

        /// <summary>
        /// The arrow colors in the three states.
        /// </summary>
        protected Color[,] arrowColors = new Color[3, 8];

        /// <summary>
        /// The arrow border colors.
        /// </summary>
        protected Color[] arrowBorderColors = new Color[4];

        /// <summary>
        /// The background colors.
        /// </summary>
        protected Color[] backgroundColors = new Color[5];

        /// <summary>
        /// The track colors.
        /// </summary>
        protected Color[] trackColors = new Color[2];

        #endregion

        #region constructor

        /// <summary>
        /// Initializes static members of the <see cref="NScrollBarRenderer"/> class.
        /// </summary>
        internal NScrollBarRenderer()
        {
            drawThumbGrip = true;

            // hot state
            thumbColors[0, 0] = Color.FromArgb(96, 111, 148); // border color
            thumbColors[0, 1] = Color.FromArgb(232, 233, 233); // left/top start color
            thumbColors[0, 2] = Color.FromArgb(230, 233, 241); // left/top end color
            thumbColors[0, 3] = Color.FromArgb(233, 237, 242); // right/bottom line color
            thumbColors[0, 4] = Color.FromArgb(209, 218, 228); // right/bottom start color
            thumbColors[0, 5] = Color.FromArgb(218, 227, 235); // right/bottom end color
            thumbColors[0, 6] = Color.FromArgb(190, 202, 219); // right/bottom middle color
            thumbColors[0, 7] = Color.FromArgb(96, 11, 148); // left/top line color

            // over state
            thumbColors[1, 0] = Color.FromArgb(60, 110, 176);
            thumbColors[1, 1] = Color.FromArgb(187, 204, 228);
            thumbColors[1, 2] = Color.FromArgb(205, 227, 254);
            thumbColors[1, 3] = Color.FromArgb(252, 253, 255);
            thumbColors[1, 4] = Color.FromArgb(170, 207, 247);
            thumbColors[1, 5] = Color.FromArgb(219, 232, 251);
            thumbColors[1, 6] = Color.FromArgb(190, 202, 219);
            thumbColors[1, 7] = Color.FromArgb(233, 233, 235);

            // pressed state
            thumbColors[2, 0] = Color.FromArgb(60, 110, 176);
            thumbColors[2, 1] = Color.FromArgb(187, 204, 228);
            thumbColors[2, 2] = Color.FromArgb(205, 227, 254);
            thumbColors[2, 3] = Color.FromArgb(252, 253, 255);
            thumbColors[2, 4] = Color.FromArgb(170, 207, 247);
            thumbColors[2, 5] = Color.FromArgb(219, 232, 251);
            thumbColors[2, 6] = Color.FromArgb(190, 202, 219);
            thumbColors[2, 7] = Color.FromArgb(233, 233, 235);

            /* picture of colors and indices
             *(0,0)
             * -----------------------------------------------
             * |                                             |
             * | |-----------------------------------------| |
             * | |                  (2)                    | |
             * | | |-------------------------------------| | |
             * | | |                (0)                  | | |
             * | | |                                     | | |
             * | | |                                     | | |
             * | |3|                (1)                  |3| |
             * | |6|                (4)                  |6| |
             * | | |                                     | | |
             * | | |                (5)                  | | |
             * | | |-------------------------------------| | |
             * | |                  (12)                   | |
             * | |-----------------------------------------| |
             * |                                             |
             * ----------------------------------------------- (15,17)
             */

            // hot state
            arrowColors[0, 0] = Color.FromArgb(223, 236, 252);
            arrowColors[0, 1] = Color.FromArgb(207, 225, 248);
            arrowColors[0, 2] = Color.FromArgb(245, 249, 255);
            arrowColors[0, 3] = Color.FromArgb(237, 244, 252);
            arrowColors[0, 4] = Color.FromArgb(244, 249, 255);
            arrowColors[0, 5] = Color.FromArgb(244, 249, 255);
            arrowColors[0, 6] = Color.FromArgb(251, 253, 255);
            arrowColors[0, 7] = Color.FromArgb(251, 253, 255);

            // over state
            arrowColors[1, 0] = Color.FromArgb(205, 222, 243);
            arrowColors[1, 1] = Color.FromArgb(186, 208, 235);
            arrowColors[1, 2] = Color.FromArgb(238, 244, 252);
            arrowColors[1, 3] = Color.FromArgb(229, 237, 247);
            arrowColors[1, 4] = Color.FromArgb(223, 234, 247);
            arrowColors[1, 5] = Color.FromArgb(241, 246, 254);
            arrowColors[1, 6] = Color.FromArgb(243, 247, 252);
            arrowColors[1, 7] = Color.FromArgb(250, 252, 255);

            // pressed state
            arrowColors[2, 0] = Color.FromArgb(215, 220, 225);
            arrowColors[2, 1] = Color.FromArgb(195, 202, 210);
            arrowColors[2, 2] = Color.FromArgb(242, 244, 245);
            arrowColors[2, 3] = Color.FromArgb(232, 235, 238);
            arrowColors[2, 4] = Color.FromArgb(226, 228, 230);
            arrowColors[2, 5] = Color.FromArgb(230, 233, 236);
            arrowColors[2, 6] = Color.FromArgb(244, 245, 245);
            arrowColors[2, 7] = Color.FromArgb(245, 247, 248);

            // background colors
            backgroundColors[0] = Color.FromArgb(235, 237, 239);
            backgroundColors[1] = Color.FromArgb(252, 252, 252);
            backgroundColors[2] = Color.FromArgb(247, 247, 247);
            backgroundColors[3] = Color.FromArgb(238, 238, 238);
            backgroundColors[4] = Color.FromArgb(240, 240, 240);

            // track colors
            trackColors[0] = Color.FromArgb(204, 204, 204);
            trackColors[1] = Color.FromArgb(220, 220, 220);

            // arrow border colors
            arrowBorderColors[0] = Color.FromArgb(135, 146, 160);
            arrowBorderColors[1] = Color.FromArgb(140, 151, 165);
            arrowBorderColors[2] = Color.FromArgb(128, 139, 153);
            arrowBorderColors[3] = Color.FromArgb(99, 110, 125);
        }

        #endregion

        #region methods

        #region public methods

        /// <summary>
        /// Draw This BorderColor
        /// </summary>
        /// <param name="g"></param>
        /// <param name="enable"></param>
        /// <param name="color"></param>
        /// <param name="rect"></param>
        public virtual void DrawBorder(
           Graphics g,
           bool enable,
           Color color,          
           Rectangle rect)
        {
            System.Windows.Forms.ControlPaint.DrawBorder(g, rect, color, System.Windows.Forms.ButtonBorderStyle.Solid);
        }

        /// <summary>
        /// Draws the background.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="orientation">The <see cref="ScrollBarOrientation"/>.</param>
        public virtual void DrawBackground(
           Graphics g,
           Rectangle rect,
           ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }

            if (rect.IsEmpty || g.IsVisibleClipEmpty
               || !g.VisibleClipBounds.IntersectsWith(rect))
            {
                return;
            }

            if (orientation == ScrollBarOrientation.Vertical)
            {
                DrawBackgroundVertical(g, rect);
            }
            else
            {
                DrawBackgroundHorizontal(g, rect);
            }
        }

        /// <summary>
        /// Draws the channel ( or track ).
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="state">The scrollbar state.</param>
        /// <param name="orientation">The <see cref="ScrollBarOrientation"/>.</param>
        public virtual void DrawTrack(
           Graphics g,
           Rectangle rect,
           ScrollBarState state,
           ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }

            if (rect.Width <= 0 || rect.Height <= 0
               || state != ScrollBarState.Pressed || g.IsVisibleClipEmpty
               || !g.VisibleClipBounds.IntersectsWith(rect))
            {
                return;
            }

            if (orientation == ScrollBarOrientation.Vertical)
            {
                DrawTrackVertical(g, rect);
            }
            else
            {
                DrawTrackHorizontal(g, rect);
            }
        }

        /// <summary>
        /// Draws the thumb.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="state">The <see cref="ScrollBarState"/> of the thumb.</param>
        /// <param name="orientation">The <see cref="ScrollBarOrientation"/>.</param>
        public virtual void DrawThumb(
           Graphics g,
           Rectangle rect,
           ScrollBarState state,
           ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }

            if (rect.IsEmpty || g.IsVisibleClipEmpty
               || !g.VisibleClipBounds.IntersectsWith(rect)
               || state == ScrollBarState.Disabled)
            {
                return;
            }             
        }

        /// <summary>
        /// Draws the grip of the thumb.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="orientation">The <see cref="ScrollBarOrientation"/>.</param>
        public virtual void DrawThumbGrip(
           Graphics g,
           Rectangle rect,
           ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }

            if (rect.IsEmpty || g.IsVisibleClipEmpty
               || !g.VisibleClipBounds.IntersectsWith(rect))
            {
                return;
            }

            if (drawThumbGrip)
            {
                // get grip image
                using (Image gripImage = ScrollBarResources.GripNormal)
                {
                    // adjust rectangle and rotate grip image if necessary
                    Rectangle r = AdjustThumbGrip(rect, orientation, gripImage);

                    // adjust alpha channel of grip image
                    using (ImageAttributes attr = new ImageAttributes())
                    {
                        attr.SetColorMatrix(
                           new ColorMatrix(new float[][] {
                  new[] { 1F, 0, 0, 0, 0 },
                  new[] { 0, 1F, 0, 0, 0 },
                  new[] { 0, 0, 1F, 0, 0 },
                  new[] { 0, 0, 0,  .8F, 0 },
                  new[] { 0, 0, 0, 0, 1F }
                           }),
                           ColorMatrixFlag.Default,
                           ColorAdjustType.Bitmap
                        );

                        // draw grip image
                        g.DrawImage(gripImage, r, 0, 0, r.Width, r.Height, GraphicsUnit.Pixel, attr);
                    }
                }
            }
            
        }

        /// <summary>
        /// Draws an arrow button.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="state">The <see cref="ScrollBarArrowButtonState"/> of the arrow button.</param>
        /// <param name="arrowUp">true for an up arrow, false otherwise.</param>
        /// <param name="orientation">The <see cref="ScrollBarOrientation"/>.</param>
        public virtual void DrawArrowButton(
           Graphics g,
           Rectangle rect,
           ScrollBarArrowButtonState state,
           bool arrowUp,
           ScrollBarOrientation orientation)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }

            if (rect.IsEmpty || g.IsVisibleClipEmpty
               || !g.VisibleClipBounds.IntersectsWith(rect))
            {
                return;
            }

            if (orientation == ScrollBarOrientation.Vertical)
            {
                DrawArrowButtonVertical(g, rect, state, arrowUp);
            }
            else
            {
                DrawArrowButtonHorizontal(g, rect, state, arrowUp);
            }
        }

        #endregion

        #region protected methods

        /// <summary>
        /// Draws the background.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        protected void DrawBackgroundVertical(Graphics g, Rectangle rect)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(
               rect,
               backgroundColors[3],
               backgroundColors[4],
               LinearGradientMode.Horizontal))
            {
                g.FillRectangle(brush, rect);
            }
        }

        /// <summary>
        /// Draws the background.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        protected void DrawBackgroundHorizontal(Graphics g, Rectangle rect)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(
               rect,
               backgroundColors[3],
               backgroundColors[4],
               LinearGradientMode.Vertical))
            {
                g.FillRectangle(brush, rect);
            }
        }

        /// <summary>
        /// Draws the channel ( or track ).
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        protected void DrawTrackVertical(Graphics g, Rectangle rect)
        {
            Rectangle innerRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height); 
            using (LinearGradientBrush brush = new LinearGradientBrush(
               innerRect,
               trackColors[0],
               trackColors[1],
               LinearGradientMode.Horizontal))
            {
                g.FillRectangle(brush, innerRect);
            }
        }

        /// <summary>
        /// Draws the channel ( or track ).
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        protected void DrawTrackHorizontal(Graphics g, Rectangle rect)
        {
            Rectangle innerRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
                // new Rectangle(rect.Left, rect.Top + 1, rect.Width, rect.Height - 2);
            using (LinearGradientBrush brush = new LinearGradientBrush(
               innerRect,
               trackColors[0],
               trackColors[1],
               LinearGradientMode.Vertical))
            {
                g.FillRectangle(brush, innerRect);
            }
        }

        /// <summary>
        /// Adjusts the thumb grip according to the specified <see cref="ScrollBarOrientation"/>.
        /// </summary>
        /// <param name="rect">The rectangle to adjust.</param>
        /// <param name="orientation">The scrollbar orientation.</param>
        /// <param name="gripImage">The grip image.</param>
        /// <returns>The adjusted rectangle.</returns>
        /// <remarks>Also rotates the grip image if necessary.</remarks>
        protected Rectangle AdjustThumbGrip(
           Rectangle rect,
           ScrollBarOrientation orientation,
           Image gripImage)
        {
            Rectangle r = rect;

            if (orientation == ScrollBarOrientation.Vertical)
            {
                r.X += (r.Width / 2) - (gripImage.Width / 2);
                r.Y += (r.Height / 2) - (gripImage.Height / 2);
            }
            else
            {
                gripImage.RotateFlip(RotateFlipType.Rotate90FlipNone);

                r.X += (r.Width / 2) - (gripImage.Width / 2);
                r.Y += (r.Height / 2) - (gripImage.Height / 2);
            }

            r.Width = gripImage.Width;
            r.Height = gripImage.Height;

            return r;
        }

        /// <summary>
        /// Draws the thumb.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="state">The <see cref="ScrollBarState"/> of the thumb.</param>
        protected void DrawThumbVertical(
           Graphics g,
           Rectangle rect,
           ScrollBarState state)
        {
            int index = 0;

            switch (state)
            {
                case ScrollBarState.Hot:
                    {
                        index = 1;
                        break;
                    }

                case ScrollBarState.Pressed:
                    {
                        index = 2;
                        break;
                    }
            }

            float round = 0.0f;

            Rectangle bound = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
                       
            // draw right gradient
            if (index == 0)
            {
                using (LinearGradientBrush brush = new LinearGradientBrush(
                   bound,
                   thumbColors[index, 4],
                   thumbColors[index, 5],
                   LinearGradientMode.Horizontal))
                {
                    //brush.InterpolationColors = new ColorBlend(3)
                    //{
                    //    Colors = new[]
                    //             {
                    //           thumbColors[index, 4],
                    //           thumbColors[index, 6],
                    //           thumbColors[index, 5]
                    //        },
                    //    Positions = new[] { 0f, .5f, 1f }
                    //};

                    g.FillRectangle(brush, rect);
                }
            }
            else
            {
                using (LinearGradientBrush brush = new LinearGradientBrush(
                   bound,
                   thumbColors[index, 4],
                   thumbColors[index, 5],
                   LinearGradientMode.Horizontal))
                {
                    g.FillRectangle(brush, rect);
                }                
            }            

            g.SmoothingMode = SmoothingMode.AntiAlias;

            // draw border  
            using (Pen p = new Pen(thumbColors[index, 0]))
            {
                using (GraphicsPath path = CreateRoundPath(bound, round))
                {
                    g.DrawPath(p, path);
                }                
            }

            g.SmoothingMode = SmoothingMode.None;
        }

        /// <summary>
        /// Draws the thumb.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="state">The <see cref="ScrollBarState"/> of the thumb.</param>
        protected void DrawThumbHorizontal(
           Graphics g,
           Rectangle rect,
           ScrollBarState state)
        {
            int index = 0;

            switch (state)
            {
                case ScrollBarState.Hot:
                    {
                        index = 1;
                        break;
                    }

                case ScrollBarState.Pressed:
                    {
                        index = 2;
                        break;
                    }
            }

            float round = 0.0f;

            Rectangle bound = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);

            // draw right gradient
            if (index == 0)
            {
                using (LinearGradientBrush brush = new LinearGradientBrush(
                   bound,
                   thumbColors[index, 4],
                   thumbColors[index, 5],
                   LinearGradientMode.Vertical))
                {
                    //brush.InterpolationColors = new ColorBlend(3)
                    //{
                    //    Colors = new[]
                    //             {
                    //           thumbColors[index, 4],
                    //           thumbColors[index, 6],
                    //           thumbColors[index, 5]
                    //        },
                    //    Positions = new[] { 0f, .5f, 1f }
                    //};

                    g.FillRectangle(brush, bound);
                }
            }
            else
            {
                using (LinearGradientBrush brush = new LinearGradientBrush(
                   bound, thumbColors[index, 4],
                   thumbColors[index, 5],
                   LinearGradientMode.Vertical))
                {
                    g.FillRectangle(brush, bound);
                }                
            }            

            g.SmoothingMode = SmoothingMode.AntiAlias;            

            // draw border
            using (Pen p = new Pen(thumbColors[index, 0]))
            {
                using (GraphicsPath path = CreateRoundPath(bound, round))
                {
                    g.DrawPath(p, path);
                }
            }

            g.SmoothingMode = SmoothingMode.None;
        }

        /// <summary>
        /// Draws an arrow button.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="state">The <see cref="ScrollBarArrowButtonState"/> of the arrow button.</param>
        /// <param name="arrowUp">true for an up arrow, false otherwise.</param>
        protected void DrawArrowButtonVertical(
           Graphics g,
           Rectangle rect,
           ScrollBarArrowButtonState state,
           bool arrowUp)
        {
            using (Image arrowImage = GetArrowDownButtonImage(state))
            {
                if (arrowUp)
                {
                    arrowImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
                }

                g.DrawImage(arrowImage, rect);
            }
        }

        /// <summary>
        /// Draws an arrow button.
        /// </summary>
        /// <param name="g">The <see cref="Graphics"/> used to paint.</param>
        /// <param name="rect">The rectangle in which to paint.</param>
        /// <param name="state">The <see cref="ScrollBarArrowButtonState"/> of the arrow button.</param>
        /// <param name="arrowUp">true for an up arrow, false otherwise.</param>
        protected void DrawArrowButtonHorizontal(
           Graphics g,
           Rectangle rect,
           ScrollBarArrowButtonState state,
           bool arrowUp)
        {
            using (Image arrowImage = GetArrowDownButtonImage(state))
            {
                if (arrowUp)
                {
                    arrowImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
                }
                else
                {
                    arrowImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
                }

                g.DrawImage(arrowImage, rect);
            }
        }

        /// <summary>
        /// Draws the arrow down button for the scrollbar.
        /// </summary>
        /// <param name="state">The button state.</param>
        /// <returns>The arrow down button as <see cref="Image"/>.</returns>
        protected Image GetArrowDownButtonImage(
           ScrollBarArrowButtonState state)
        {
            Rectangle rect = new Rectangle(0, 0, 15, 17);
            Bitmap bitmap = new Bitmap(15, 17, PixelFormat.Format32bppArgb);
            bitmap.SetResolution(72f, 72f);

            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.SmoothingMode = SmoothingMode.None;
                g.InterpolationMode = InterpolationMode.Low;

                int index = -1;

                switch (state)
                {
                    case ScrollBarArrowButtonState.UpHot:
                    case ScrollBarArrowButtonState.DownHot:
                        {
                            index = 1;

                            break;
                        }

                    case ScrollBarArrowButtonState.UpActive:
                    case ScrollBarArrowButtonState.DownActive:
                        {
                            index = 0;

                            break;
                        }

                    case ScrollBarArrowButtonState.UpPressed:
                    case ScrollBarArrowButtonState.DownPressed:
                        {
                            index = 2;

                            break;
                        }
                }

                if (index != -1)
                {
                    //using (Pen p1 = new Pen(arrowBorderColors[0]),
                    //   p2 = new Pen(arrowBorderColors[1]))
                    //{
                    //    g.DrawLine(p1, rect.X, rect.Y, rect.Right - 1, rect.Y);
                    //    g.DrawLine(p2, rect.X, rect.Bottom - 1, rect.Right - 1, rect.Bottom - 1);
                    //}

                    //rect.Inflate(0, -1);

                    //using (LinearGradientBrush brush = new LinearGradientBrush(
                    //   rect,
                    //   arrowBorderColors[2],
                    //   arrowBorderColors[1],
                    //   LinearGradientMode.Vertical))
                    //{
                    //    ColorBlend blend = new ColorBlend(3)
                    //    {
                    //        Positions = new[] { 0f, .5f, 1f },
                    //        Colors = new[] {
                    // arrowBorderColors[2],
                    // arrowBorderColors[3],
                    // arrowBorderColors[0] }
                    //    };

                    //    brush.InterpolationColors = blend;

                    //    using (Pen p = new Pen(brush))
                    //    {
                    //        g.DrawLine(p, rect.X, rect.Y, rect.X, rect.Bottom - 1);
                    //        g.DrawLine(p, rect.Right - 1, rect.Y, rect.Right - 1, rect.Bottom - 1);
                    //    }
                    //}

                    //rect.Inflate(0, 1);                     

                    using (LinearGradientBrush brush = new LinearGradientBrush(
                       rect,
                       arrowColors[index, 4],
                       arrowColors[index, 5],
                       LinearGradientMode.Vertical))
                    {
                        g.FillRectangle(brush, rect);
                    }

                }

                using (Image arrowIcon = ScrollBarResources.ScrollBarArrowDown)
                {
                    if (state == ScrollBarArrowButtonState.DownDisabled
                       || state == ScrollBarArrowButtonState.UpDisabled)
                    {
                        System.Windows.Forms.ControlPaint.DrawImageDisabled(
                           g,
                           arrowIcon,
                           3,
                           6,
                           Color.Transparent);
                    }
                    else
                    {
                        g.DrawImage(arrowIcon, 3, 6);
                    }
                }
            }

            return bitmap;
        }

        /// <summary>
        /// Creates a rounded rectangle.
        /// </summary>
        /// <param name="r">The rectangle to create the rounded rectangle from.</param>
        /// <param name="radiusX">The x-radius.</param>
        /// <param name="radiusY">The y-radius.</param>
        /// <returns>A <see cref="GraphicsPath"/> object representing the rounded rectangle.</returns>
        protected GraphicsPath CreateRoundPath(
           Rectangle r,
           float radius)
        {
            // create new graphics path object
            GraphicsPath path = new GraphicsPath();

            if (radius > 0)
            {
                // add top left arc
                path.AddArc(r.X, r.Y, radius, radius, 180, 90);
                // add top right arc
                path.AddArc(r.Width - radius, r.Y, radius, radius, 270, 90);
                // add bottom right arc
                path.AddArc(r.Width - radius, r.Height - radius, radius, radius, 0, 90);
                // add bottom left arc
                path.AddArc(r.X, r.Height - radius, radius, radius, 90, 90);
               
            }
            else
            {
                path.AddRectangle(new RectangleF(r.X, r.Y, r.Width, r.Height));
            }

            // close path
            path.CloseFigure();

            return path;
        }

        #endregion

        #endregion
    }
}
